package bean;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * <描述> Bean对象处理调用类
 * 
 * @author 王永弟
 * @since JAF1.0
 * @copyright 广州从兴电子开发有限公司-电子渠道业务部
 * @date 2011-5-19
 * @log <重大修改日志，格式：YYYY-MM-DD 修改人 修改内容>
 */
public class BeanUtils {
	/**
	 * <方法描述> 根据属性名，获取相应的属性类
	 * 
	 * @param beanClass
	 *            类名
	 * @param fieldName
	 *            属性名，可支持多级，如sid,group.sid
	 * @return 字段对应的类型
	 * @example <调用范例>
	 */
	public static Class<?> getFieldType(Class<?> beanClass, String fieldName) {
		try {
			return BeanUtilsBean.getInstance().getFieldType(beanClass, fieldName);
		} catch (Exception e) {
			String message = "get fieldType:" + fieldName + " of " + beanClass + " error!";
			throw new BeanParseException(message, e);
		}
	}

	/**
	 * <方法描述> 获取类属性的setter方法，对于多级属性名，按顺序返回多个Method<br>
	 * 如group.sid，返回两个Method，Method[0]为group的setter方法，Method[1]为sid的setter方法
	 * 
	 * @param beanClass
	 *            类名
	 * @param fieldName
	 *            属性名，可支持多级，如sid,group.sid
	 * @return setter方法
	 * @example <调用范例>
	 */
	public static Method[] getSetterMethod(Class<?> beanClass, String fieldName) {
		return BeanUtilsBean.getInstance().getSetterMethod(beanClass, fieldName);
	}

	/**
	 * <方法描述> 获取类属性的getter方法，对于多级属性名，按顺序返回多个Method<br>
	 * 如group.sid，返回两个Method，Method[0]为group的getter方法，Method[1]为sid的getter方法
	 * 
	 * @param beanClass
	 *            类名
	 * @param fieldName
	 *            属性名，可支持多级，如sid,group.sid
	 * @return getter方法
	 * @example <调用范例>
	 */
	public static Method[] getGetterMethod(final Class<?> beanClass, final String fieldName) {
		return BeanUtilsBean.getInstance().getGetterMethod(beanClass, fieldName);
	}

	/**
	 * <方法描述> 获取当个setter方法，当前方法仅在当前属性中，不支持多级
	 * 
	 * @param beanClass
	 *            类名
	 * @param fieldName
	 *            属性名，不支持多级
	 * @return setter方法
	 * @example <调用范例>
	 */
	public static Method getSingleSetterMethod(final Class<?> beanClass, final String fieldName) {
		try {
			return BeanUtilsBean.getInstance().getSingleSetterMethod(beanClass, fieldName);
		} catch (Exception e) {
			String message = "get field setter method error,field:" + fieldName + ",class:" + beanClass;
			throw new BeanParseException(message, e);
		}
	}

	/**
	 * <方法描述> 获取当个getter方法，当前方法仅在当前属性中，不支持多级
	 * 
	 * @param beanClass
	 *            类名
	 * @param fieldName
	 *            属性名，不支持多级
	 * @return getter方法
	 * @example <调用范例>
	 */
	public static Method getSingleGetterMethod(final Class<?> beanClass, final String fieldName) {
		try {
			return BeanUtilsBean.getInstance().getSingleGetterMethod(beanClass, fieldName);
		} catch (Exception e) {
			String message = "get field getter method error,field:" + fieldName + ",class:" + beanClass;
			throw new BeanParseException(message, e);
		}
	}

	/**
	 * <方法描述> 获取属性值，支持多级属性值的获取
	 * 
	 * @param bean
	 *            对象
	 * @param fieldName
	 *            属性名，支持多级获取，如获取group.sid的值
	 * @return 属性值
	 * @example <调用范例>
	 */
	public static Object getProperty(final Object bean, final String fieldName) {
		return BeanUtilsBean.getInstance().getProperty(bean, fieldName);
	}

	/**
	 * <方法描述> 获取Int型属性值，支持多级属性值的获取，当对象为空时，返回0
	 * 
	 * @param bean
	 *            对象
	 * @param fieldName
	 *            属性名，支持多级获取，如获取group.sid的值
	 * @return int型属性值
	 */
	public static int getIntProperty(final Object bean, final String fieldName) {
		return BeanUtilsBean.getInstance().getIntProperty(bean, fieldName);
	}

	/**
	 * <方法描述> 获取属性名，根据多个方法获取，获取的值为最后一个方法对应的值
	 * 
	 * @param bean
	 *            对象值
	 * @param method
	 *            方法，第一个方法为bean对象里的方法
	 * @return 属性值
	 * @example <调用范例>
	 */
	public static Object getProperty(final Object bean, final Method... method) {
		return BeanUtilsBean.getInstance().getProperty(bean, method);
	}

	/**
	 * <方法描述> 将String的值，存放入bean的字段里
	 * 
	 * @param bean
	 *            数据bean
	 * @param fieldName
	 *            字段名称，如：sid,group.sid
	 * @param value
	 *            字符串值，会自动根据数据模型中的类型，来转换
	 * @example <调用范例> <br>
	 *          Attribute attribute = new Attribute(); <br>
	 *          BeanUtilsBean.getInstance().setProperty(attribute,"sid","111"); <br>
	 *          BeanUtilsBean.getInstance().setProperty(attribute,"group.sortNum","1");
	 */
	public static void setProperty(Object bean, String fieldName, String value) {
		try {
			BeanUtilsBean.getInstance().setProperty(bean, fieldName, value);
		} catch (Exception e) {
			String message = "set property error, bean:" + bean + ",fieldName:" + fieldName + ",value:" + value;
			throw new BeanParseException(message, e);
		}
	}

	/**
	 * <方法描述> 设置属性值，支持多级属性名
	 * 
	 * @param bean
	 *            对象值
	 * @param fieldName
	 *            属性名，支持多级，如支持group.sid的设值方式
	 * @param value
	 *            属性值
	 * @example <调用范例>
	 */
	public static void setProperty(Object bean, String fieldName, Object value) {
		try {
			BeanUtilsBean.getInstance().setProperty(bean, fieldName, value);
		} catch (Exception e) {
			String message = "set property error, bean:" + bean + ",fieldName:" + fieldName + ",value:" + value;
			throw new BeanParseException(message, e);
		}
	}

	/**
	 * <方法描述> 根据方法设置属性值，仅限单级，即当前Method为bean里面的方法
	 * 
	 * @param bean
	 *            对象值
	 * @param method
	 *            setter方法
	 * @param value
	 *            属性值
	 * @example <调用范例>
	 */
	public static void setProperty(Object bean, Method method, Object value) {
		try {
			BeanUtilsBean.getInstance().setProperty(bean, method, value);
		} catch (Exception e) {
			String message = "set property error, bean:" + bean + ",method:" + method + ",value:" + value;
			throw new BeanParseException(message, e);
		}
	}

	/**
	 * <方法描述> 根据方法设置属性值，支持多级设值，要求getters/setters中的方法个数一致
	 * 
	 * @param bean
	 *            对象实例
	 * @param value
	 *            属性值
	 * @param getters
	 *            getter方法数组，按属性级排序，如group.sid，应该有两个getter方法，Method[0]为group的getter方法，Method[1]
	 *            为sid的getter方法
	 * @param setters
	 *            setter方法数组，与getter的方法个数相同
	 * @example <调用范例>
	 */
	public static void setProperty(Object bean, Object value, Method[] getters, Method[] setters) {
		try {
			BeanUtilsBean.getInstance().setProperty(bean, value, getters, setters);
		} catch (Exception e) {
			String message = "set property error, bean:" + bean + ",getter methods:" + Arrays.toString(getters)
					+ ",setter methods:" + Arrays.toString(setters) + ",value:" + value;
			throw new BeanParseException(message, e);
		}
	}

	/**
	 * <方法描述> 将属性值放到bean中
	 * 
	 * @param bean
	 *            对象实例
	 * @param properties
	 *            属性Map
	 */
	public static void populate(Object bean, Map<String, String> properties) {
		try {
			BeanUtilsBean.getInstance().populate(bean, properties);
		} catch (Exception e) {
			String message = "populate map to bean error,bean:" + bean + ",properties:" + properties;
			throw new BeanParseException(message, e);
		}
	}

	/**
	 * <方法描述> 判断对象中是否函数该字段
	 * 
	 * @param clazz
	 *            对象类
	 * @param fieldName
	 *            属性名
	 * @return true or false
	 */
	public static boolean hasField(Class<?> clazz, String fieldName) {
		return BeanUtilsBean.getInstance().hasField(clazz, fieldName);
	}

	/**
	 * <方法描述> 是否使用缓存
	 * 
	 * @return true or false
	 */
	public static boolean isUseCache() {
		return BeanUtilsBean.getInstance().isUseCache();
	}

	/**
	 * <方法描述> 设置是否采用缓存，默认采用缓存
	 * 
	 * @param useCache
	 *            true or false
	 */
	public static void setUseCache(boolean useCache) {
		BeanUtilsBean.getInstance().setUseCache(useCache);
	}

	/**
	 * <方法描述> 根据属性类型，获取属性的所有值对象，包含指定类型的数组
	 * 
	 * @param <T>
	 * @param bean
	 * @param type
	 * @return
	 */
	public static <T> List<T> getObjectsByType(Object bean, Class<T> type) {
		return BeanUtilsBean.getInstance().getObjectsByType(bean, type);
	}

	/**
	 * 把对象属性都转换成字符串
	 * 
	 * @param object
	 * @return
	 * @example <调用范例>
	 */
	public static String beanToString(Object object) {
		return BeanUtilsBean.getInstance().beanToString(object);
	}
}

